-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[charts] Remove colors
prop from SparkLineChart
.
#16494
[charts] Remove colors
prop from SparkLineChart
.
#16494
Conversation
<SparkLineChart data={data} colors={['red']} /> | ||
<SparkLineChart data={data} colors={fn} /> | ||
<SparkLineChart data={data} colors={(mode) => (mode === 'light' ? ['black'] : ['white'])} /> | ||
<SparkLineChart data={data} colors="red" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is valid since colors
can be an array of strings or a function, but added it to ensure that we handle invalid well (i.e., by not applying any transformation).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed this test case because TypeScript wasn't happy with invalid properties.
Deploy preview: https://deploy-preview-16494--material-ui-x.netlify.app/ Updated pages: |
CodSpeed Performance ReportMerging #16494 will not alter performanceComparing Summary
|
(<React.Fragment> | ||
<SparkLineChart data={data} color={['red'][0]} /> | ||
<SparkLineChart data={data} color={typeof fn === "function" ? mode => fn(mode)?.[0] : fn} /> | ||
<SparkLineChart data={data} color={mode => (mode => (mode === 'light' ? ['black'] : ['white']))(mode)?.[0]} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might seem a bit confusing, but what I'm doing is:
Given an arrow function declaration fnDecl
, transform it into: mode => (fnDecl)(mode)?.[0]
.
We need the optional chaining operator because undefined
is a valid value for colors
, so we need be careful not to access [0]
of an undefined value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's tricky and I think most of the users will prefer to just rewrite the function by themself.
return ( | ||
(<React.Fragment> | ||
<SparkLineChart data={data} color={['red'][0]} /> | ||
<SparkLineChart data={data} color={typeof fn === "function" ? mode => fn(mode)?.[0] : fn} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this is a valid approach.
This introduces a slight runtime performance hit because, when codemodding, we can't guarantee whether fn
is a function or an array.
If you think this or another example are too complex, I can just remove this and leave this as an unhandled case.
// Don't know how to handle this case | ||
} | ||
|
||
// Only apply transformation if we know how to handle it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any best practice for letting the user know where we caught an unhandled case? I know we aren't covering 100% of the cases, and some are easy to detect, but hard to fix. It would be nice if we could let the user know which ones have been detected to guide them towards where they need to do a manual fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we currently notify unhandled cases
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can propose that though 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's run in the dev console, a console.warn
should do the job
// prettier-ignore | ||
return ( | ||
(<React.Fragment> | ||
<SparkLineChart data={data} color={['red']?.[0]} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I followed a "better safe than sorry" approach here. Adding the optional chain operator might save us from some crashes in edge cases. Happy to remove it if you think that's too much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what will happen to var
when var=['blue']
?
936f04b
to
e25f08c
Compare
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
e25f08c
to
237df3b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like you had a deep thaughts about the different ways users could mess with that breaking change :)
Why not for the two first cases in example. But the last one looks more confusing than helping.
Maybe adding a comment in the user codebase like
// codemod-message: We replaced `colors` by `color`. Make sure this props receives a string or a function returning a string.
It seems JSXAttributes have a leadingComments
property for that
Or some console.warning could do the job too.
And in the changelog an instruction about how to run this specific codemod
// Don't know how to handle this case | ||
} | ||
|
||
// Only apply transformation if we know how to handle it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's run in the dev console, a console.warn
should do the job
colorAttributeExpression = j.chainExpression( | ||
j.optionalMemberExpression(colorsAttributeExpression, j.literal(0)), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not
colorAttributeExpression = j.chainExpression( | |
j.optionalMemberExpression(colorsAttributeExpression, j.literal(0)), | |
); | |
colorAttributeExpression = colorsAttributeExpression.elements[0]; |
Which should do
- <SparkLineChart data={data} color={['red']} />
+ <SparkLineChart data={data} color={'red'} />
Instead of
- <SparkLineChart data={data} color={['red']} />
+ <SparkLineChart data={data} color={['red']?.[0]} />
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly for safety reasons, didn't want to change user's code too much, but maybe it's fine. I'm not able to come up with a common use case where it might break 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To provide more information: if we use colorsAttributeExpression.elements[0]
, then weird cases like colors={[bool ? 'red' : 'blue']}
will break. By doing ?.[0]
they will still work, and the user can remove the ?.[0]
if it isn't necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's hope people did bool ? ['red'] : ['blue']
:)
More seriously, you can not write a codemod that is 100% safe. The level of abstraction of the AST is too low.
For me, the idea is to guess what users might have done and provide a solution.
By doing ?.[0]
you end up in a situation where 100% of modified lines will work, but 100% modified lines will need to be modified by the user. (I don't see someone keeping this ?.[0]
.
The other solution does not guaranty 100% correctness, but
- If it works, it's the natural solution
- If it does not work, the line should be easy to find from the git diff
By the way why does it break? I tried with AST explorer, and it seems that it does the expected behavior
- colors={[test ? 'black' : 'white']}
+ color={test ? 'black' : 'white'}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, those are good points. I don't have a lot of codemods, so I'm still trying to understand where to do the trade-offs.
I was leaning more on being 100% correct even if the final code isn't as desirable, but I'm ok with opting for the simpler solution.
I'll simplify this 👍
By the way why does it break? I tried with AST explorer, and it seems that it does the expected behavior
Yeah, you're right. I'll update the code 👍
(<React.Fragment> | ||
<SparkLineChart data={data} color={['red'][0]} /> | ||
<SparkLineChart data={data} color={typeof fn === "function" ? mode => fn(mode)?.[0] : fn} /> | ||
<SparkLineChart data={data} color={mode => (mode => (mode === 'light' ? ['black'] : ['white']))(mode)?.[0]} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's tricky and I think most of the users will prefer to just rewrite the function by themself.
Yeah, maybe too much 😛
Yeah, that sounds like a good idea. I'll take a look into doing something like that. If all messages start with
Yeah, if we add any
👍 |
@alexfauquette due to adding the comment blocks we kind of lost the idempotency. I say kind of because it's the comments that broke the idempotency, however having more than one comment doesn't really break the code, so I'm not sure if it's a problem. If you run the codemod multiple times you'll get more comments than you should, but that doesn't break the code per se. I can add it back, but it'll take me some time as I was having trouble finding previous element in jscodeshift. Apparently there's no API for that. Let me know if I should add it back or this is acceptable 👍 |
…o appease TypeScript.
9f1c17d
to
31ee2a7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good 👍
I added a commit to fix the TS CI. I hope it will pass
Having TS ok with the actual/expected is most of the time just impossible, because one is written to match previous API which by definition does not respect the typing of the new one
Remove
colors
prop fromSparkLineChart
.In #16477, I deprecated the
colors
prop, but we can still do breaking changes for v8. This will reduce the maintenance burden slightly.Also added codemod to migrate from the old
colors
prop to the newcolor
prop.